package com.jsecode.protocol.gid22;

import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;


/**
 * 消息头
 * 包序列号 功能ID    设备ID    数据长度
 *   1      1        6         2
 *
 * @author grind
 * @date Mar 28, 2014 3:05:46 PM
 * @version 1.0
 */
public class GidHeader {
    protected static Logger logger = LoggerFactory.getLogger("Gid22-GidHeader");
    
    // 定义协议的常量
    public final static int HEAD_LEN = 10;// 基础信息的大小

    private short msgSeq; // u8 包序列号
    private int msgId; // u8 功能ID
    private long devId; // 6 bytes 设备ID
    private int bodyLen; // u16 数据长度

    // 协议外数据
    protected int size = HEAD_LEN;

    public GidHeader(){
    }
    
    public GidHeader(int msgId, String terminalId){
        this(msgId, Long.valueOf(terminalId));
    }

    public GidHeader(int msgId, long devId){
        this((short)getMsgUpSerial(), msgId, devId, 0);
    }

    public GidHeader(short msgSeq, int msgId, long devId){
        this(msgSeq, msgId, devId, 0);
    }

    public GidHeader(short msgSeq, int msgId, long devId, int bodyLen){
        this.msgSeq = msgSeq;
        this.msgId = msgId;
        this.devId = devId;
        this.bodyLen = bodyLen;
    }
    
    /**
     * 打包头信息
     * @param size
     * @return
     */
    public ByteBuf pack() {
        int capacity = HEAD_LEN;

        ByteBuf buf = Unpooled.buffer(capacity);
        buf.writeByte(msgSeq);
        buf.writeByte(msgId);
        GidUtil.writeLong6(buf, devId);
        buf.writeShort(bodyLen);
        
        return buf;
    }

    /**
     * 解析头信息
     * @param srcBuf 传入的头信息的源数据, readIndex指向解析头
     * @return -1 - 错误; 0 - 成功
     */
    public int unpack(ByteBuf srcBuf) {
        if (srcBuf.readableBytes() < HEAD_LEN) {
            logger.warn("the head len is too small.");
            return -1;
        }
        msgSeq = srcBuf.readUnsignedByte();
        msgId = srcBuf.readUnsignedByte();
        devId = GidUtil.readLong6(srcBuf);
        bodyLen = srcBuf.readUnsignedShort();
        
        return 0;
    }

    /** 返回字符串的device id */
    public String getDeviceId() {
        return Long.toString(devId);
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("msgSeq:0x").append(Integer.toHexString(msgSeq)).append(",");
        sb.append("msgId:0x").append(Integer.toHexString(msgId)).append(",");
        sb.append("devId:").append(devId).append(",");
        sb.append("bodyLen:").append(bodyLen);
        
        return sb.toString();
    }


    public short getMsgSeq(){
        return msgSeq;
    }

    public void setMsgSeq(short msgSeq){
        this.msgSeq = msgSeq;
    }

    public int getMsgId(){
        return msgId;
    }

    public void setMsgId(int msgId){
        this.msgId = msgId;
    }

    public long getDevId(){
        return devId;
    }

    public void setDevId(long devId){
        this.devId = devId;
    }

    public int getBodyLen(){
        return bodyLen;
    }

    public void setBodyLen(int bodyLen){
        this.bodyLen = bodyLen;
    }


    /** 发送消息的序列号，从0开始，到最大数结束 */
    private static AtomicInteger msgUpSerial = new AtomicInteger(0); // 最大为 1个字节
    public static int getMsgUpSerial() {
        if (msgUpSerial.getAndAdd(1) >= 0xff) {
            msgUpSerial.set(0);
        }
        return msgUpSerial.get();
    }
    
}
